<!--
 * @Autor: 王琛
 * @Description: 模型加载器
 * @Copyright: 版权归个人所有
-->
<style lang="stylus" scoped>
#modelLoading {
  width: 100%;
  height: 100%;
  position: relative;
}
</style>


<template>
  <div id="modelLoading" :element-loading-text="_data.modeSpeedOfProgress"></div>
</template>


<script setup lang="ts">
import {nextTick, onMounted, reactive} from "vue";
import {useRouter} from "vue-router";
import {useStore} from "vuex";
import * as Three from "three";
import {ElLoading} from "element-plus"
import {OBJLoader} from 'three/examples/jsm/loaders/OBJLoader.js'
import {MTLLoader} from 'three/examples/jsm/loaders/MTLLoader.js'
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js'

const _props = defineProps({
  config: {
    type: Object,
    default: () => {
      return {
        name: "MPA",
        Children: [
          {
            ShowName: '',
            name: '',
          }
        ]
      }
    },
  },
})
const _store = useStore();
const _state = _store.state;

const _data = reactive({
  // 模型加载状态
  modeLoading: true,
  // 模型加载进度
  modeSpeedOfProgress: 0,
});


// 渲染器
let renderer: any = null;
// 场景
let scene: any = null;
// 正交投影相机
let camera: any = null;
// 模型解析器
let loaderObj: any = null;
onMounted(() => {
  // 模型加载等待状态
  let progressWaiting: any = null;
  // 创建渲染器
  renderer = new Three.WebGLRenderer({antialias: true, alpha: true, logarithmicDepthBuffer: true})
  scene = new Three.Scene();
  camera = new Three.PerspectiveCamera(45, window.innerWidth / (window.innerHeight - 57), .4, 3000);
  // camera = new Three.PerspectiveCamera(45, 4/3, .5, 20000);
  let trackballControls = new OrbitControls(camera, renderer.domElement);
  renderer.outputEncoding = Three.sRGBEncoding;
  renderer.setSize(window.innerWidth, window.innerHeight - 57);
  renderer.setClearColor(new Three.Color("#CCCCCC"));//画布颜色
  renderer.shadowMap.enabled = true;//激活阴影
  trackballControls.rotateSpeed = 1;
  trackballControls.enableDamping = true;
  trackballControls.dampingFactor = .1;
  trackballControls.enablePan = true;
  trackballControls.enableZoom = true;
  trackballControls.minDistance = 600;
  trackballControls.maxDistance = 6000;
  trackballControls.maxPolarAngle = 1.5;
  trackballControls.minPolarAngle = 0;
  trackballControls.target.set(0, 0, 0);
  trackballControls.update()

  const ThreeColor = new Three.Color("#fffff")
  // 环境光
  let light1 = new Three.HemisphereLight(ThreeColor, ThreeColor, 1);
  light1.position.set(0, 10, 0);
  scene.add(light1);
  //添加材质灯光阴影
  let spotLight = new Three.DirectionalLight(0xffffff, 1);
  spotLight.castShadow = false;
  spotLight.position.set(0, 10, 0);
  spotLight.intensity = 2
  scene.add(spotLight);
  camera.position.x = 1000;
  camera.position.y = 1000;
  camera.position.z = 1000;
  camera.lookAt(scene.position);
  scene.add(camera);
  // 创建解析材质
  let mtlLoader = new MTLLoader()
  // 创建解析模型
  let objLoader = new OBJLoader();
  // 模型的名称
  const modeName = _props.config?.name || "A";
  // 服务器线上模型的存放地址
  const ServerStatic3DMode = import.meta.env.VITE_MODE_NAME !== "dev" ? `/ProjectInfo/Static/3DMode/${_state.appId}` : "./3DMode";


  const ModePath = `${ServerStatic3DMode}${_props.config?.path ? "/" : ""}${_props.config?.path || ""}/`;

  mtlLoader.setPath(ModePath);
  objLoader.setPath(ModePath);
  mtlLoader.load(`${modeName}.mtl`, function (materials) {
    materials.preload()
    objLoader.setMaterials(materials)
    // 加载obj
    objLoader.load(`${modeName}.obj`, function (obj) {
      obj.position.x = 0;
      obj.position.y = -2;
      // 模型文件太大，缩小一下比例，方便显示
      obj.scale.set(0.2, 0.2, 0.2)
      obj.children.forEach((item) => {
        if (item.type == "Mesh") {
          item.material.color = ThreeColor;
          item.material.transparent = true;
          item.material.opacity = 1;
          item.material.side = Three.DoubleSide;
          item.material.needsupdate = true;
        }
      })
      // 添加到场景
      scene.add(obj)
    }, (xhr) => {
      if (!progressWaiting) progressWaiting = ElLoading.service(document.getElementById("modelLoading"));
      const modeSpeedOfProgress: number = parseInt((xhr.loaded / xhr.total) * 100);
      progressWaiting.setText(`努力加载中 ${modeSpeedOfProgress}%`)
      modeSpeedOfProgress >= 100 && progressWaiting.close();
    })
  })
  document.getElementById("modelLoading").appendChild(renderer.domElement);

  function renderScene() {
    trackballControls.update();
    requestAnimationFrame(renderScene);
    renderer.render(scene, camera);
  }

  renderScene();
})


</script>

